<template>
  <div
    v-loading="loading"
    v-init-screen-h="10"
    class="camera_box w100"
    element-loading-text="摄像头加载中"
    element-loading-spinner="el-icon-loading"
    element-loading-background="rgba(3,10,70, 0.8)"
  >
    <dv-border-box-12 ref="box12ref1" class="right_content ">
      <CheckboxList
        class="three_list"
        style="height: 40%;overflow: auto;"
        :iWind="iWind"
        :showStreamIcon="false"
        :codeStreamList="codeStreamList"
        :checkList="checkList"
        @changeCheck="handleChangeCheck"
      ></CheckboxList>
      <el-calendar style="height:48%;" v-model="calendarVal">
        <!-- 这里使用的是 2.5 slot 语法，对于新项目请使用 2.6 slot 语法-->
        <!-- date, -->
        <template slot="dateCell" slot-scope="{ data }">
          <div
            class="flex-x flex-center w100 h-full date_text"
            :style="{
              background: data.isSelected ? 'rgb(140, 197, 255)' : ''
            }"
          >
            <!-- <span
              v-if="showDateIcon(data, date)"
              class="el-icon-caret-right date_text_icon"
            ></span> -->
            {{ data.day.split("-")[2] }}
          </div>
        </template>
      </el-calendar>
      <el-button
        style="height: 6%;"
        type="primary"
        size="small"
        :loading="searchBtnLoading"
        @click="handleSearch"
        >查询</el-button
      >
    </dv-border-box-12>
    <dv-border-box-12 ref="box12ref2" class="play_content">
      <div id="playWind" class="w100"></div>
      <BackToolbar
        v-if="checkList.length"
        :currentVideo="currentVideo"
        @handleCamera="handleCamera"
        @setVolumeAll="setVolumeAll"
        :isPlay="isPlay"
        @playOrStopAll="playOrStopAll"
        @fullScreen="fullScreen"
        :showTime="showTime"
      ></BackToolbar>
      <div class="timeline flex-x">
        <!-- :backgroundColor="'rgb(0, 0, 0)'" -->
        <TimeLine
          ref="Timeline2"
          :initTime="time2"
          @timeChange="timeChange2"
          :timeSegments="timeSegments"
          @click_timeSegments="click_timeSegments"
          @click_timeline="onClickTimeLine"
          @dragTimeChange="onDragTimeChange"
        ></TimeLine>
        <div class="flex-x" style="color: #fff;margin-left: 10px;">
          <span
            class="el-icon-circle-plus-outline"
            @click="zoomChange(false)"
          ></span>
          <div style="font-size: 14px;width: 46px;" class="flex-x flex-center">
            {{ getZoomText }}
          </div>
          <span class="el-icon-remove-outline" @click="zoomChange(true)"></span>
        </div>
      </div>
    </dv-border-box-12>
  </div>
</template>

<script>
import _ from "lodash";
import CheckboxList from "./components/CheckboxList.vue";
import BackToolbar from "./components/BackToolbar.vue";
import TimeLine from "@/components/TimeLine";
import moment from "moment";
import axios from "axios";
import { formatDate } from "@/filter/index";
import qs from "qs";
import {
  CAMERA_LIST,
  CODE_STREAM,
  USERNAME_PASSWORD,
  VIDEO_BAER_URL,
  ACCESS_URL,
  TIME_ZOOM
} from "./constent";
import { getDays, callMethodLimitPage } from "./utils";

export default {
  components: {
    CheckboxList,
    BackToolbar,
    TimeLine
  },
  props: {
    cameraFlag: {
      type: String,
      default: ""
    }
  },
  computed: {
    getZoomText() {
      return TIME_ZOOM[this.timeZoomPage].label;
    },
    showTime() {
      return moment(this.time2).format("YYYY-MM-DD HH:mm:ss");
    },
    // 获取当前月的开始和结束时间
    startEndTime() {
      const data = getDays(formatDate(new Date())).allDay;
      return {
        startTime: data[0],
        endTime: data[data.length - 1]
      };
    },

    // 当前的天是否有回放存在
    showDateIcon() {
      return function(data, date) {
        const { day } = data;
        const isShow = this.dateList.find(item => {
          const d = formatDate(
            item.searchMatchItem.timeSpan.startTime,
            "YYYY-MM-DD"
          );
          return d == day;
        });
        return isShow;
      };
    },

    // 是否有视频正在播放
    isPlay() {
      return this.checkList.every(item => item.iWind == -1);
    },
    // 当前选中的视频
    currentVideo() {
      return this.checkList.find(item => item.iWind == this.iWind);
    }
  },
  data() {
    return {
      searchBtnLoading: false,
      timeZoomPage: 2,
      cameraObj: {},
      realTime: Date.now(),
      dateList: [],
      calendarVal: new Date(),
      loading: false,
      jsDecoder: null,
      iWind: 0,
      VideoInputChannelList: [],
      checkList: [],
      codeStreamList: CODE_STREAM,
      windowNumber: 3,
      pageNumber: -1,
      devIndex: "17031824-26B8-184D-84B5-161937A2C988",
      time2: moment(new Date()).format("YYYY-MM-DD HH:mm:ss"),
      timer: null,
      timeSegments: [
        // {
        //   name: "时间段1",
        //   beginTime: new Date("2023-02-06 10:00:00").getTime(),
        //   endTime: new Date("2023-02-06 23:00:00").getTime(),
        //   color: "#4994EC",
        //   startRatio: 0.75,
        //   endRatio: 1
        // },
        // {
        //   name: "时间段2",
        //   beginTime: new Date("2023-02-06 02:00:00").getTime(),
        //   endTime: new Date("2023-02-06 18:00:00").getTime(),
        //   color: "#4994EC",
        //   startRatio: 0.75,
        //   endRatio: 1
        // }
      ],
      currentDateValue: moment(new Date()).format("YYYY-MM-DD HH:mm:ss")
    };
  },
  watch: {
    cameraFlag: {
      handler: function() {
        if (this.cameraFlag == "回放") {
          setTimeout(() => {
            this.init();
          }, 500);
        }
      },
      immediate: true
    },
    // 有bug 晚点改
    "$store.state.app.sidebar.opened"() {
      setTimeout(() => {
        if (this.$refs.box12ref1) {
          this.$refs.box12ref1.initWH();
          this.$refs.box12ref2.initWH();
          // 从新设置容器的宽高
          this.resizeWH();
        }
      }, 500);
    }
  },
  destroyed() {},
  async mounted() {},
  //时间轴
  beforeDestroy() {
    console.log("销毁 :>> ");
    this.stopRealPlayAll();
    window.removeEventListener("resize", this.resizeWH);
    clearTimeout(this.timer);
  },

  methods: {
    async init() {
      try {
        this.loading = true;
        this.devIndex = await this.getDevIndex();
        this.checkList = await this.getVideoList();
        this.loading = false;
        // 此处解决 双击放大之后 无法全屏的问题
        window.addEventListener("resize", this.resizeWH);
        this.$nextTick(() => {
          // 初始化容器
          this.rendererPlay();
          // 初始化监听函数
          this.initPlugin();
        });
      } catch (error) {
        this.$msg("摄像头获取失败");
        this.loading = false;
      }
      // this.checkList = CAMERA_LIST.map(item => {
      //   return {
      //     VideoInputChannel: {
      //       ...item.VideoInputChannel
      //     },
      //     isCheck: false, //单击选中
      //     iWind: -1, //当前播放的窗口
      //     codeStreamValue: CODE_STREAM[1].value,
      //     isVolume: false //是否开启声音
      //   };
      // });
      this.cameraObj = _.cloneDeep(this.checkList[0]);
    },
    // 查询当前摄像头存在的回放
    async handleSearch() {
      this.time2 = this.calendarVal;
      this.currentDateValue = this.calendarVal;
      this.$refs.Timeline2.setTime(this.time2);
      this.stopRealPlayAll();
      const sd = {
        startTime: this.$moment(
          formatDate(this.calendarVal, "YYYY-MM-DD [00:00:00]")
        )
          .add(-1, "days")
          .format("YYYY-MM-DDTHH:mm:ss[Z]"),
        endTime: this.$moment(
          formatDate(this.calendarVal, "YYYY-MM-DD [23:59:59]")
        )
          .add(1, "days")
          .format("YYYY-MM-DDTHH:mm:ss[Z]")
      };
      this.dateList = [];
      if (JSON.stringify(this.cameraObj) != "{}") {
        this.searchBtnLoading = true;
        try {
          this.dateList = await callMethodLimitPage(
            this.getPlayBackList,
            this.getCameraParams(sd, this.cameraObj.VideoInputChannel.id),
            0,
            []
          );
          this.searchBtnLoading = false;
          console.log("this.dateList :>> ", this.dateList);
          if (this.dateList.length == 0) {
            this.$msg("当前日期不存在视频回放");
            return;
          }
          this.timeSegments = this.dateList.map((item, index) => {
            const timeSpan = item.searchMatchItem.timeSpan;
            return {
              name: "时间段" + index,
              beginTime: new Date(formatDate(timeSpan.startTime)).getTime(),
              endTime: new Date(formatDate(timeSpan.endTime)).getTime(),
              color: "#4994EC",
              startRatio: 0.75,
              endRatio: 1
            };
          });
        } catch (error) {
          this.searchBtnLoading = false;
        }
      }
    },
    // 获取当前摄像头的参数
    getCameraParams(sd, cameraId) {
      const trackID = `${cameraId}01`;
      return {
        CMSearchDescription: {
          searchID: "C7E71364-4560-0002-6EDD-16ED17B01CCD",
          trackIDList: [
            {
              trackID: Number(trackID)
            }
          ],
          timeSpanList: [
            {
              timeSpan: {
                ...sd
              }
            }
          ],
          contentTypeList: [
            {
              contentType: "video"
            }
          ],
          maxResults: 40,
          searchResultPostion: 0,
          metadataList: [
            {
              metadataDescriptor: "recordType.meta.std-cgi.com"
            }
          ]
        }
      };
    },
    // 获取回放列表
    // http://192.168.11.204:8088/ISAPI/ContentMgmt/search?format=json&devIndex=17031824-26B8-184D-84B5-161937A2C988
    getPlayBackList(data) {
      return new Promise((reslove, reject) => {
        axios({
          method: "post",
          url: `${VIDEO_BAER_URL}/ContentMgmt/search?format=json&devIndex=${this.devIndex}`,
          data: data
        }).then(res => {
          const list = res.data.CMSearchResult.matchList;
          console.log("res :>> ", list);
          reslove({
            results: list || [],
            numResults: res.data.CMSearchResult.numOfMatches
          });
        });
      });
    },
    // 时间轴
    timeChange2(t) {
      this.time2 = t;
    },
    click_timeSegments(arr) {
      console.log("onClickTimeSegments", arr);
      alert("点击了：" + arr[0].name);
    },
    onClickTimeLine(time, date) {
      this.time = time;
      console.log("onClickTimeLine", time, date);
    },
    onDragTimeChange(...args) {
      this.currentDateValue = this.$moment(args[0]).format(
        "YYYY-MM-DD HH:mm:ss"
      );
      this.realTime = this.currentDateValue;
      // 如果有视频正在播放,就直接开始播放
      if (this.currentVideo) {
        this.playCamera();
      }
    },
    zoomChange(flg) {
      // 下一页
      if (flg) {
        this.timeZoomPage++;
      } else {
        // 上一页
        this.timeZoomPage--;
      }
      if (this.timeZoomPage < 0) {
        this.timeZoomPage = 0;
        return;
      }
      if (this.timeZoomPage >= TIME_ZOOM.length) {
        this.timeZoomPage = TIME_ZOOM.length - 1;
        return;
      }
      this.$refs.Timeline2.setZoom(TIME_ZOOM[this.timeZoomPage].value);
    },
    checkFlag(e) {
      if (e === "2") {
        // this.time2 = moment(new Date()).format("YYYY-MM-DD HH:mm:ss");
        this.timer = setInterval(() => {
          this.time2 += 1000;
          this.$refs.Timeline2.setTime(this.time2);
        }, 1000);
      } else {
        clearTimeout(this.timer);
      }
    },
    // 获取录像机id
    getDevIndex() {
      return new Promise((reslove, reject) => {
        axios({
          method: "post",
          url: `${VIDEO_BAER_URL}/ContentMgmt/DeviceMgmt/deviceList?format=json`,
          data: {
            SearchDescription: {
              position: 0,
              maxResult: 100,
              Filter: {
                key: "",
                devType: "",
                protocolType: ["ehomeV5"],
                devStatus: ["online", "offline"]
              }
            }
          }
        })
          .then(res => {
            if (res.data.SearchResult.MatchList.length) {
              const devIndex =
                res.data.SearchResult.MatchList[0].Device.devIndex;
              reslove(devIndex);
            } else {
              reject();
            }
          })
          .catch(err => {
            reject();
          });
      });
    }, // 拍照
    handleCamera() {
      if (this.currentVideo) {
        this.jsDecoder.JS_CapturePicture(
          this.iWind,
          this.currentVideo.VideoInputChannel.name,
          "jpg"
        );
      }
    },
    // 关闭所有声音
    closeSoundAll() {
      this.checkList.forEach(item => {
        item.isVolume = false;
        if (item.iWind !== -1) {
          this.closeSound(item.iWind);
        }
      });
    },
    // 一键开始/关闭声音
    setVolumeAll(val) {
      // 开启之前先关闭其他的声音
      this.checkList.forEach(item => {
        if (item.iWind == this.iWind) {
          item.isVolume = item.isVolume ? false : true;
          if (item.isVolume) {
            this.openSound();
          } else {
            this.closeSound(item.iWind);
          }
        } else if (item.iWidth !== -1) {
          item.isVolume = false;
        } else {
          item.isVolume = false;
          this.closeSound(item.iWind);
        }
      });
    },

    // 控制声音和大小开关
    openSound() {
      this.jsDecoder.JS_OpenSound(this.iWind);
    },
    closeSound(iWind) {
      this.jsDecoder.JS_CloseSound(iWind);
    },
    //还原数组的播放状态
    initList() {
      this.checkList.forEach(item => {
        item.iWind = -1;
      });
    },
    // 关闭全部
    stopRealPlayAll() {
      this.checkFlag();
      this.initList();
      if (this.jsDecoder) {
        this.jsDecoder.JS_StopRealPlayAll();
      }
    },
    destroyWorker() {
      this.jsDecoder.JS_DestroyWorker();
    },
    // 开始播放
    async playCamera() {
      if (this.dateList.length == 0) {
        this.$msg("请先查询当天是否存在回放");
        return;
      }
      // 播放之前先暂停全部
      this.stopRealPlayAll();
      let rtspUrl = "";
      const s = this.$moment(this.currentDateValue)
        .add(-8, "hours")
        .format("YYYYMMDDTHHmmss[Z]");
      this.dateList.forEach(item => {
        const startTime = this.$moment(
          item.searchMatchItem.timeSpan.startTime
        ).format("YYYY-MM-DD HH:mm:ss");
        const endTime = this.$moment(
          item.searchMatchItem.timeSpan.endTime
        ).format("YYYY-MM-DD HH:mm:ss");
        const is = this.$moment(this.currentDateValue).isBetween(
          startTime,
          endTime,
          null,
          "()"
        );
        if (is) {
          let d = this.dateList[this.dateList.length - 1].searchMatchItem
            .timeSpan.endTime;
          d = this.$moment(d)
            .add(-8, "hours")
            .format("YYYYMMDDTHHmmss[Z]");
          const urlArr = item.searchMatchItem.mediaSegmentDescriptor.playbackURI.split(
            "?"
          );
          const rtspIP = urlArr[0];
          const rtspParams = urlArr[1];
          let params = qs.parse(rtspParams);
          params = {
            ...params,
            starttime: s,
            endtime: d
          };
          console.log("params :>> ", qs.stringify(params));
          console.log("rtspIP :>> ", rtspIP);
          rtspUrl = `${rtspIP}?${qs.stringify(params)}`;
        }
      });
      if (rtspUrl) {
        await this.realplay(rtspUrl, 0);
        this.checkList.forEach(item => {
          if (
            item.VideoInputChannel.id == this.cameraObj.VideoInputChannel.id
          ) {
            item.iWind = this.iWind;
          } else {
            item.iWind = -1;
          }
        });
        this.checkFlag("2");
      } else {
        this.$msg("当前时间段没有可播放的视频");
      }
    },
    // 播放/暂停全部
    async playOrStopAll() {
      // 停止所有播放
      if (!this.isPlay) {
        this.stopRealPlayAll();
      } else {
        this.playCamera();
      }
    },
    // 获取摄像头列表
    getVideoList() {
      return new Promise((reslove, reject) => {
        axios({
          method: "get",
          url: `${VIDEO_BAER_URL}/System/Video/inputs/channels?format=json&devIndex=${this.devIndex}`
        })
          .then(res => {
            const list = res?.data?.VideoInputChannelList;
            const newList = list.map(item => {
              return {
                VideoInputChannel: {
                  ...item.VideoInputChannel
                },
                isCheck: false, //单击选中
                iWind: -1, //当前播放的窗口
                codeStreamValue: CODE_STREAM[1].value,
                isVolume: false //是否开启声音
              };
            });
            reslove(newList);
          })
          .catch(err => {
            reject();
          });
      });
    },
    // 全屏
    fullScreen() {
      this.fullSreen();
    },
    // 开始预览播放
    realplay(previewUrl, iWind, sd) {
      console.log("拿到地址准备播放 :>> ", sd, iWind, previewUrl);
      let that = this;
      return new Promise((reslove, reject) => {
        this.jsDecoder
          .JS_Play(
            ACCESS_URL,
            {
              playURL: previewUrl, //play URL,
              auth: USERNAME_PASSWORD
            },
            iWind
            // sd.szStartTime,
            // sd.szStopTime
          )
          .then(
            function() {
              console.log("播放成功");
              reslove(true);
            },
            function() {
              that.$msg("播放失败");
              that.stopRealPlayAll();
              reslove(false);
            }
          );
      });
    },
    // 获取播放的url
    getRtspUrl(videoId, codeStreamValue) {
      return new Promise((reslove, reject) => {
        axios({
          method: "post",
          url: `${VIDEO_BAER_URL}/System/streamMedia?format=json&devIndex=${this.devIndex}`,
          data: {
            StreamInfo: {
              id: videoId,
              streamType: "sub",
              method: "preview"
            }
          }
        })
          .then(res => {
            console.log("res :>> ", res);
            // reslove(
            //   `rtsp://${RTSP_URL}/dac/realplay/${this.devIndex}${videoId}/${codeStreamValue}/TCP?streamform=rtp`
            // );
            reslove(res.data.MediaAccessInfo.URL);
          })
          .catch(err => {
            this.$msg("播放地址获取失败");
          });
      });
    },
    // 重新设置窗口宽高
    resizeWH() {
      const { width, height } = this.getContentWH();
      if (this.jsDecoder) {
        this.jsDecoder.JS_Resize(width, height);
      }
    },
    // 获取容器宽高
    getContentWH() {
      const width = document.getElementById("playWind").offsetWidth - 5;
      const height = document.getElementById("playWind").offsetHeight;
      return {
        width,
        height
      };
    },
    // 初始化容器
    rendererPlay() {
      const { width, height } = this.getContentWH();
      this.jsDecoder = new JSPlugin({
        szId: "playWind",
        iWidth: width,
        iHeight: height,
        iMaxSplit: 1, //最大拆分
        iCurrentSplit: 1, //默认拆分
        szBasePath: "./jsPlugin",
        oStyle: {
          border: "#3B5F95",
          // box-shadow: 0 0 2px 2px rgba(71,167,235,.86);
          borderSelect: "#F7CE46",
          background: "rgba(58,58,89,0)"
        },
        bOnlySupportJSDecoder: false
      });
    },

    // 全屏
    fullSreen() {
      this.jsDecoder.JS_FullScreenDisplay(true);
    },
    // 单个全屏
    fullScreenSingle() {
      this.jsDecoder.JS_FullScreenSingle(this.iWind);
    },
    // 停止播放
    videoStop(iWind) {
      this.jsDecoder.JS_Stop(iWind);
    },

    // 选择播放的摄像头 (单击选中的)
    async handleChangeCheck(rowObj, index) {
      this.cameraObj = _.cloneDeep(rowObj);
    },
    // 初始化
    initPlugin() {
      let that = this;
      this.jsDecoder.JS_SetWindowControlCallback({
        windowEventSelect: iWndIndex => {
          this.iWind = iWndIndex;
          this.$emit("updateIWind", iWndIndex);
        },
        pluginErrorHandler: function(iWndIndex, iErrorCode, oError) {
          console.log(iWndIndex, iErrorCode, oError);
          // 报错之后数组内部状态初始化
          that.checkList.forEach(item => {
            if (item.iWind == iWndIndex) {
              item.iWind = -1;
            }
          });
        },
        performanceLack: function() {
          console.log("性能不足");
        }
      });
    }
  }
};
</script>

<style lang="scss" scoped>
.date_text {
  position: relative;
}
.date_text_icon {
  position: absolute;
  top: 0;
  right: 0;
  color: #409eff;
}
.camera_box {
  display: flex;
  .right_content {
    width: 20%;
    padding: 20px;
    /deep/ {
      .el-calendar-table .el-calendar-day:hover {
        background-color: #1e93de;
      }
      .el-calendar {
        border-radius: 6px;
        overflow: hidden;
        background-color: #4b98e1;
        .el-calendar__title {
          color: #fff;
        }
        .el-calendar-table tr td:first-child {
          border-color: #8fbeeb;
        }
        .el-calendar-table td {
          border-color: #8fbeeb;
        }
        .el-button {
          background-color: transparent;
          color: #fff;
          border: 1px solid #8fbeeb;
        }
        .current {
          .date_text {
            color: #fff;
          }
        }
        .el-calendar__button-group {
          text-align: center;
        }
        .el-calendar__header {
          flex-direction: column;
        }
        .el-calendar__header {
          padding: 4px;
        }
        .el-calendar__body {
          padding: 2px;
          height: calc(100% - 55px);
          .el-calendar-table {
            height: 100%;
            thead {
              th {
                font-size: 16px;
                padding: 5px 0;
                color: #fff;
              }
            }
          }
          td {
            //   padding: 6px;
            text-align: center;
            .el-calendar-day {
              font-size: 14px;
              height: 100%;
              display: flex;
              padding: 0;
              margin: 0;
              align-items: center;
              justify-content: center;
            }
          }
        }
      }

      .border-box-content {
        overflow: auto;
        display: flex;
        flex-direction: column;
        justify-content: space-between;
      }
      .three_list {
      }
      .three_list,
      .border-box-content {
        &::-webkit-scrollbar-track {
          background-color: inherit;
          -webkit-border-radius: 0;
          -moz-border-radius: 0;
          border-radius: 0;
        }
        &::-webkit-scrollbar-thumb {
          background-color: #5dcbff;
          -webkit-border-radius: 2em;
          -moz-border-radius: 2em;
          border-radius: 2em;
        }
        &::-webkit-scrollbar {
          width: 4px !important;
        }
        &::-webkit-scrollbar-corner {
          /* background-color: #5dcbff; */
          display: none;
        }
      }
    }
  }
  .play_content {
    #playWind {
      // 高度 权重加到最高,不然会被行内的覆盖掉 导致高度出现计算不准确
      height: calc(100% - 35px - 35px) !important;
    }
    padding: 20px;
    width: 80%;
    height: 100%;
    // /deep/ .parent-wnd {
    //   display: flex;
    //   flex-wrap: wrap;
    // }
  }
  .timeline {
    height: 35px;
    width: calc(100% - 5px);
    background-color: rgb(38, 38, 38);
  }

  /deep/ .el-radio__label {
    color: #fff;
  }
  /deep/ .el-radio__input.is-checked + .el-radio__label {
    color: #409eff !important;
  }
}
</style>
